unit UCommon;

{$mode delphi}

interface

uses
  Classes, SysUtils, variants, dateutils, zstream;

type

{ TFUN }
 TFUN = class
public
  {=========  字符串处理  ========}
  class function Encrypt(const str: string): string;
  class function Decrypt(const str: string): string;
  class function GetPY(aHanzi : string) : char;
  class function GzpCompress(const str: string): AnsiString;
  class function UnzipString(const gzs: AnsiString): string;
  {==========  时间处理  ============}
  class function DayOfWeekEx(dt: TDateTime): string;
  //Variant 转换成 Stream 的函数
  class function VariantToMemStream ( const v :olevariant ): TMemoryStream;
  //Stream 转换成 Variant  的函数
  class function MemStreamToVariant ( Stream : TStream ): OleVariant;
  {=========  位处理  ========}
  class function SetBit_1(X: Longword;  nDigit: Integer): Longword;//位置从0算起
  class function SetBit_0(X: Longword;  nDigit: Integer): Longword;//位置从0算起
  class function GetBit01(X: Longword;  nDigit: Integer): Boolean; //位置从0算起

end;

const
  FSeedA = 67890;  // 密钥常量
  FSeedB = 56789;  // 密钥常量
  FKey  = 2018;    // 密钥钥匙

implementation

{ TFUN }
class function TFUN.Encrypt(const str: string): string;
var
  i, j, iKey:   Integer;
  strGet:  string;
begin
  strGet := str;
  iKey   := FKey;
  Result := strGet;
  for i:=1 to Length(strGet) do
  begin
    Result[i]:=Char(byte(strGet[i]) XOR(iKey shr 8));
    iKey   := (Byte(Result[I]) +iKey) *FSeedA +FSeedB;
  end;
  strGet := Result;
  Result := '';
  for i:=1 to Length(strGet) do
  begin
    j   :=   Integer(strGet[i]);
    Result:= Result +Char(65 +(j div 26)) +char(65 +(j mod 26));
  end;
end;

class function TFUN.Decrypt(const str: string): string;
var
  i, j, iKey :Integer;
  strGet  : string;
begin
  strGet := str;
  iKey   := FKey;
  Result   :='';
  for i:=1 to (Length(strGet) div 2) do
  begin
    j := (Integer(strGet[2*i-1])-65)*26;
    j := j +(Integer(strGet[2*i])-65);
    Result := Result +Char(j);
  end;
  strGet := Result;
  for   i:=1 to Length(strGet) do
  begin
    Result[i]:=Char(byte(strGet[I]) xor (iKey shr 8));
    iKey := (Byte(strGet[I]) +iKey) *FSeedA +FSeedB;
  end;
end;

class function TFUN.GetPY(aHanzi: string): char;
begin
  case WORD(aHanzi[1]) shl 8 + WORD(aHanzi[2]) of
   $B0A1..$B0C4 : result := 'A';
   $B0C5..$B2C0 : result := 'B';
   $B2C1..$B4ED : result := 'C';
   $B4EE..$B6E9 : result := 'D';
   $B6EA..$B7A1 : result := 'E';
   $B7A2..$B8C0 : result := 'F';
   $B8C1..$B9FD : result := 'G';
   $B9FE..$BBF6 : result := 'H';
   $BBF7..$BFA5 : result := 'J';
   $BFA6..$C0AB : result := 'K';
   $C0AC..$C2E7 : result := 'L';
   $C2E8..$C4C2 : result := 'M';
   $C4C3..$C5B5 : result := 'N';
   $C5B6..$C5BD : result := 'O';
   $C5BE..$C6D9 : result := 'P';
   $C6DA..$C8BA : result := 'Q';
   $C8BB..$C8F5 : result := 'R';
   $C8F6..$CBF9 : result := 'S';
   $CBFA..$CDD9 : result := 'T';
   $CDDA..$CEF3 : result := 'W';
   $CEF4..$D188 : result := 'X';
   $D189..$D4D0 : result := 'Y';
   $D4D1..$D7F9 : result := 'Z';
  else
     result:=char(32);
   end;
end;

class function TFUN.GzpCompress(const str: string): AnsiString;
var
  OutStream, InpStream, GzpStream: TStream;
begin
  Result := '';
  if Length(str)<=3 then Exit;
  try
    OutStream := TStringStream.Create('');
    GzpStream := Tcompressionstream.Create(clmax, OutStream);
    InpStream := TStringStream.Create(str);
    GzpStream.CopyFrom(InpStream, InpStream.Size);
    Tcompressionstream(GzpStream).flush;
    Result := TStringStream(OutStream).DataString;
  finally
    if AsSigned(InpStream) then InpStream.Free;
    if AsSigned(GzpStream) then GzpStream.Free;
    if AsSigned(OutStream) then OutStream.Free;
  end;
end;

class function TFUN.UnzipString(const gzs: AnsiString): string;
var
  InpStream, DzpStream: TStream;
  StrList: TStringList;
begin
  Result := '';
  if Length(gzs)<=3 then Exit;
  try
    InpStream := TStringStream.Create(gzs);
    DzpStream := TDeCompressionStream.Create(InpStream);
    StrList := TStringList.Create;
    StrList.LoadFromStream(DzpStream);
    Result := StrList.Text;
  finally
    if AsSigned(InpStream) then InpStream.Free;
    if AsSigned(DzpStream) then DzpStream.Free;
    if AsSigned(StrList) then StrList.Free;
  end;
end;

class function TFUN.DayOfWeekEx(dt: TDateTime): string;
begin
  Result := '';
  case DayofWeek(dt) of
    1: Result := '星期日';
    2: Result := '星期一';
    3: Result := '星期二';
    4: Result := '星期三';
    5: Result := '星期四';
    6: Result := '星期五';
    7: Result := '星期六';
  end;
end;

class function TFUN.VariantToMemStream(const v: olevariant): TMemoryStream;
var
  p : pointer;
  Stream : TMemoryStream;
begin
  Stream := TMemoryStream.Create;
  Stream.Position := 0;
  Stream.Size := VarArrayHighBound (v, 1) - VarArrayLowBound(v, 1) + 1;
  p := VarArrayLock (v);
  Stream.Write (p^, Stream.Size);
  VarArrayUnlock (v);
  Stream.Position := 0;
  Result := Stream;
end;

class function TFUN.MemStreamToVariant(Stream: TStream): OleVariant;
var
  p : pointer;
  v : OleVariant;
begin
  v := VarArrayCreate ([0, Stream.Size - 1], varByte);
  p := VarArrayLock (v);
  Stream.Position := 0;
  Stream.Read (p^, Stream.Size);
  VarArrayUnlock (v);
  Result := v;
end;

class function TFUN.SetBit_1(X: Longword; nDigit: Integer): Longword;
begin
  //位置从0算起
  Result := X or (1 shl nDigit);
end;

class function TFUN.SetBit_0(X: Longword; nDigit: Integer): Longword;
begin
  //位置从0算起
  Result := X and ( not(1 shl nDigit) );
end;

class function TFUN.GetBit01(X: Longword; nDigit: Integer): Boolean;
begin
  //位置从0算起
  Result := ( ( X and (1 shl nDigit) )>0 );
end;

//initialization
//finalization

end.

